import os
import uuid
import json
import xml.etree.ElementTree as ET
from datetime import datetime
from werkzeug.utils import secure_filename


class ExamImporter:
    def __init__(self, upload_folder):
        self.upload_folder = upload_folder
        self.imported_exams = []
        os.makedirs(self.upload_folder, exist_ok=True)



    def get_exam_content(self, file_path, file_ext):
        """获取试卷详细内容"""
        try:

            if file_ext == 'json':
                return self.parse_json_exam_content(file_path)
            elif file_ext == 'xml':
                return self.parse_xml_exam_content(file_path)
            else:
                return None
        except Exception as e:
            print(f"获取试卷内容失败: {str(e)}")
            return None

    def parse_json_exam_content(self, file_path):
        """解析JSON试卷内容"""
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                exam_data = json.load(f)

            # 处理嵌套的exam结构
            if 'exam' in exam_data:
                exam_data = exam_data['exam']

            content = {
                'exam_name': exam_data.get('name', exam_data.get('exam_name', '未命名试卷')),
                'subject': exam_data.get('subject', '未知学科'),
                'total_score': exam_data.get('total_score', 100),
                'time_limit': exam_data.get('time_limit', 120),
                'questions': {}
            }

            # 按题型分类题目
            questions_by_type = {
                "选择题": [],
                "多选题": [],
                "填空题": [],
                "简答题": []
            }

            type_mapping = {
                "single_choice": "选择题",
                "multiple_choice": "多选题",
                "fill_blank": "填空题",
                "short_answer": "简答题"
            }

            for q_type, chinese_type in type_mapping.items():
                type_questions = [q for q in exam_data.get('questions', []) if q.get("type") == q_type]

                for idx, question in enumerate(type_questions, 1):
                    formatted_question = {
                        "题号": str(idx),
                        "题目": question.get('text', question.get('question', '')),
                        "正确答案": question.get('answer', '')
                    }

                    if q_type in ["single_choice", "multiple_choice"]:
                        options = question.get('options', [])
                        formatted_options = {}
                        for i, opt in enumerate(options[:4]):
                            formatted_options[chr(65 + i)] = opt
                        formatted_question["选项"] = formatted_options

                    questions_by_type[chinese_type].append(formatted_question)

            content['questions'] = questions_by_type
            return content

        except Exception as e:
            print(f"解析JSON试卷内容失败: {str(e)}")
            return None


    def parse_xml_exam_content(self, file_path):
        """解析XML试卷内容"""
        try:
            tree = ET.parse(file_path)
            root = tree.getroot()

            content = {
                'exam_name': root.find('name').text if root.find('name') is not None else '未命名试卷',
                'subject': root.find('subject').text if root.find('subject') is not None else '未知学科',
                'total_score': int(root.find('total_score').text) if root.find('total_score') is not None else 100,
                'time_limit': int(root.find('time_limit').text) if root.find('time_limit') is not None else 120,
                'questions': {}
            }

            questions_by_type = {
                "选择题": [],
                "多选题": [],
                "填空题": [],
                "简答题": []
            }

            type_mapping = {
                "single_choice": "选择题",
                "multiple_choice": "多选题",
                "fill_blank": "填空题",
                "short_answer": "简答题"
            }

            questions_elem = root.find('questions')
            if questions_elem is not None:
                # 先按类型分组
                type_groups = {t: [] for t in type_mapping.keys()}
                for question_elem in questions_elem.findall('question'):
                    q_type = question_elem.get('type', 'unknown')
                    if q_type in type_groups:
                        type_groups[q_type].append(question_elem)

                # 转换每组题目格式
                for q_type, chinese_type in type_mapping.items():
                    for idx, question_elem in enumerate(type_groups[q_type], 1):
                        question_data = {
                            "题号": str(idx),
                            "题目": question_elem.find('text').text if question_elem.find('text') is not None else '',
                            "正确答案": question_elem.find('answer').text if question_elem.find(
                                'answer') is not None else ''
                        }

                        # 处理选项
                        if q_type in ["single_choice", "multiple_choice"]:
                            options_elem = question_elem.find('options')
                            formatted_options = {}
                            if options_elem is not None:
                                for i, option_elem in enumerate(options_elem.findall('option')[:4]):
                                    formatted_options[chr(65 + i)] = option_elem.text
                            question_data["选项"] = formatted_options

                        questions_by_type[chinese_type].append(question_data)

            content['questions'] = questions_by_type
            return content

        except Exception as e:
            print(f"解析XML试卷内容失败: {str(e)}")
            return None


    def parse_exam_file(self, file_path, filename):
        """解析试卷文件"""
        try:
            file_ext = filename.rsplit('.', 1)[1].lower()

            if file_ext == 'json':
                return self.parse_json_exam(file_path, filename)
            elif file_ext == 'xml':
                return self.parse_xml_exam(file_path, filename)
            else:
                return None, "不支持的文件格式"

        except Exception as e:
            return None, f"解析文件失败: {str(e)}"

    def parse_json_exam(self, file_path, filename):
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                exam_data = json.load(f)

            # 处理嵌套的exam结构
            if 'exam' in exam_data:
                exam_data = exam_data['exam']

            exam_info = {
                'id': str(uuid.uuid4()),
                'filename': filename,
                'original_name': exam_data.get('name', exam_data.get('exam_name', '未命名试卷')),
                'subject': exam_data.get('subject', '未知学科'),
                'total_questions': len(exam_data.get('questions', [])),
                'upload_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                'file_type': 'json'
            }

            return exam_info, "解析成功"

        except json.JSONDecodeError:
            return None, "JSON格式错误"
        except Exception as e:
            return None, f"解析JSON失败: {str(e)}"

    def parse_xml_exam(self, file_path, filename):
        try:
            tree = ET.parse(file_path)
            root = tree.getroot()

            exam_name = root.find('name').text if root.find('name') is not None else '未命名试卷'
            subject = root.find('subject').text if root.find('subject') is not None else '未知学科'

            questions_elem = root.find('questions')
            total_questions = len(questions_elem.findall('question')) if questions_elem is not None else 0

            exam_info = {
                'id': str(uuid.uuid4()),
                'filename': filename,
                'original_name': exam_name,
                'subject': subject,
                'total_questions': total_questions,
                'upload_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                'file_type': 'xml'
            }
            # print(exam_info)
            return exam_info, "解析成功"

        except ET.ParseError:
            return None, "XML格式错误"
        except Exception as e:
            return None, f"解析XML失败: {str(e)}"

